package forces;

import java.awt.Dimension;
import java.util.List;

import simulation.Mass;
import util.Location;
import util.Vector;

/**
 * abstract class that describes a Force.
 * @author Schwartz & Roy
 *
 */
public abstract class Force {

    //reasonable default values
    public static final double DEFAULT_MAGNITUDE = 0.0;
    public static final double DEFAULT_EXPONENT = 0.0;
    private boolean myToggle;

    /**
     * constructor sets the toggle on by default.
     */
    public Force() {
        myToggle = true;
    }

    /**
     * abstract method to be implemented by each force.
     * @param massLocation is the mass's location
     * @param bounds of the simulation
     * @return vector of the force
     */
    public abstract Vector getForceVector(Location massLocation, Dimension bounds);

    /**
     * applies the Force to each mass in the simulation.
     * @param masses is the list of all masses in simulation
     * @param bounds of the simulation
     */
    public void applyForcesToMasses(List<Mass> masses, Dimension bounds) {
        for (Mass m : masses) {
            m.applyForce(getForceVector(new Location(m.getX(), m.getY()),
                    bounds));
        }
    }

    /**
     * turns the toggle for the force on or off.
     */
    public void switchToggle() {
        myToggle = !myToggle;
    }

    /**
     * @return whether toggle is off or on.
     */
    public boolean isOn() {
        return myToggle;
    }

    /**
     * prevents tiny distances from generating massive forces.
     * @param dist is given distance
     * @return absolute value of distance, or 1 if dist < 1
     */
    public double getSafeDistance(double dist) {
        double safeDist = Math.abs(dist);
        if (safeDist != 0 && safeDist < 1) {
            return 1;
        }
        return safeDist;
    }
}
